package com.twilight.SofaStream;

import android.app.ListActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AbsListView.OnScrollListener;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.view.Gravity;
import android.util.Log;


public class RSSAdapter extends BaseAdapter implements ListView.OnScrollListener {

	Context mContext;
	ArrayList<RSSFeed> mFeeds;
	long[] mEpisodeIds = new long[0];
	private HashMap<Long,Drawable> mFeedBackgrounds = new HashMap<Long,Drawable>();
    private LayoutInflater mInflater;
    //For tracking scroll state of the ListView.
    private boolean mBusy = false;
    
	
	public RSSAdapter(Context context) {
        super();
        mContext = context;

        //Build images to identifier the feed an episode is from.
    	Resources res = mContext.getResources();
        RSSDB db = new RSSDB(mContext);
        for (RSSFeed feed : db.getFeeds()) {
        	//Convert feed title to image resource name by converting spaces into underscores and making everything lowercase...
        	String name = feed.title.replace(' ', '_').toLowerCase();
        	int identifier = res.getIdentifier(name, "drawable", "com.twilight.SofaStream");
        	if (identifier == 0) {
        		identifier = R.drawable.unknown_feed;
        	}
        	//Extract a bitmap and rework the alpha values to make a smoothly fading feed identifier
    		BitmapDrawable feed_pic = (BitmapDrawable) res.getDrawable(identifier);
        	Bitmap bitmap = feed_pic.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
        	for (int y = 0; y < 64; y++) {
        		for (int x = 0; x < 64; x++) {
        			int color = bitmap.getPixel(x, y);
        			int alpha = x * 4; //Math.min(x * 4, y * 4);
        			bitmap.setPixel(x, y, Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)));
        		}
        	}
        	BitmapDrawable image = new BitmapDrawable(bitmap);
        	image.setGravity(Gravity.RIGHT | Gravity.TOP);
        	mFeedBackgrounds.put(feed.id, image);
            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
        
        //Collect feeds and episodes
        update();
}
	
	public void update() {
		Log.d("SofaStream", "Starting update");
        RSSDB db = new RSSDB(mContext);
    	mFeeds = db.getActiveFeeds();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
		mEpisodeIds = db.getArticles(mFeeds, prefs.getBoolean("show_new", false));
		Log.d("SofaStream", "Finished update");
	}
	
	public int getCount() {
		return mEpisodeIds.length;
	}

	public Object getItem(int position) {
        RSSDB db = new RSSDB(mContext);
		return db.getArticle(mEpisodeIds[position]);
	}

	public long getItemId(int position) {
		return mEpisodeIds[position];
	}
	
	public boolean hasStableIds() { return true; }

	public void updateRowView(long id, ListView list) {
        int first = list.getFirstVisiblePosition();
        int count = list.getChildCount();
        for (int i=0; i<count; i++) {
            if (getItemId(first + i) == id) {
            	populateEpisodeView(first + i, list.getChildAt(i));
            }
        }
	}
	
	public View getView(int position, View convertView, ViewGroup parent) {
		//Log.d("SofaStream", String.format("building view for item %d", position));
		View row = null;
        if (convertView == null) {
    		row = mInflater.inflate(R.layout.episode_list_item, parent, false);
        } else {
            row = convertView;
        }

        populateEpisodeView(position, row);
        
		return row;
	}

	private void populateEpisodeView(int position, View row) {
		TextView title = (TextView) row.findViewById(R.id.EpisodeListTitle);
		TextView status = (TextView) row.findViewById(R.id.EpisodeStatus);
		TextView pubdate = (TextView) row.findViewById(R.id.EpisodeListPubDate);
		int style = R.style.ListenedItem;
		if (!mBusy) {
             // Null tag means the view has the correct data
            row.setTag(null);
 			RSSItem article = (RSSItem) getItem(position);
			row.setBackgroundDrawable(mFeedBackgrounds.get(article.feedId));
			//row.setBackgroundResource(R.drawable.feed_background);
			title.setText(article.title);
			if (article.downloadstate == RSSItem.downloadstates.DOWNLOADED) {
				style = R.style.DownloadedItem;
				status.setText(mContext.getResources().getString(R.string.downloaded_text));
			} else if (article.downloadstate == RSSItem.downloadstates.DOWNLOADING) {
				style = R.style.DownloadingItem;
				//long percent = article.downloadprogress * 100 / article.filesize;
				//status.setText(String.format("Downloading: %d%%", percent));
				status.setText(mContext.getResources().getString(R.string.downloading_text));
			} else if (article.downloadstate == RSSItem.downloadstates.QUEUED) {
				style = R.style.QueuedItem;
				status.setText(mContext.getResources().getString(R.string.queued_text));
			} else if (article.downloadstate == RSSItem.downloadstates.FAILED) {
				style = R.style.FailedItem;
				status.setText(mContext.getResources().getString(R.string.download_failed_text));
			} else {
				if (article.listened) {
					style = R.style.ListenedItem;
				} else {
					style = R.style.NewItem;
				}
				status.setText("");
			}
			if (article.pubdate != null) {
				DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT);
				String sizestring = mContext.getResources().getString(R.string.unknown_filesize);
				try {
					sizestring = Formatter.formatFileSize (mContext, article.filesize);
				} catch (Exception e) {
					e.printStackTrace();
				}
				pubdate.setText(String.format("%s - %s", df.format(article.pubdate), sizestring));
			}
        } else {
            title.setText(mContext.getResources().getString(R.string.loading_text));
            pubdate.setText("");
            status.setText("");
            row.setBackgroundDrawable(null);
            // Non-null tag means the view still needs to load it's data
            row.setTag(this);
        }
		title.setTextAppearance(mContext, style);
		status.setTextAppearance(mContext, style);
	}
	
	
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
	}

	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// Poached from Android's API Demos, List13.java. :)
        switch (scrollState) {
        case OnScrollListener.SCROLL_STATE_IDLE:
            mBusy = false;
            
            int first = view.getFirstVisiblePosition();
            int count = view.getChildCount();
            for (int i=0; i<count; i++) {
                View child = view.getChildAt(i);
                if (child.getTag() != null) {
                    populateEpisodeView(first + i, child);
                	child.setTag(null);
                }
            }
            break;
        case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
            mBusy = true;
            break;
        case OnScrollListener.SCROLL_STATE_FLING:
            mBusy = true;
            break;
        }
	}

}


